#include <my_header.h>

#define CONSUMERNUM 3
#define PRODUCENUM  2

typedef struct Node{
    int data;
    struct Node* next;
}Node_t;

typedef struct  Queue
{
    /* data */
    Node_t *front;
    Node_t *tail;
    int size;
    int maxsize;
}Queue_t;

typedef struct Share
{
    /* data */
    Queue_t *que;
    pthread_mutex_t mutx;
    pthread_cond_t prod_cond;
    pthread_cond_t cons_cond;

}Share_t;

int Queinit(Queue_t** que,int max){
    // 修正：传入指针的指针，分配内存并返回给调用者
    *que=(Queue_t*)calloc(1,sizeof(Queue_t));
    (*que)->front=NULL;
    (*que)->tail=NULL;
    (*que)->size=0;
    (*que)->maxsize=max;
    return 1;
}

void Queprint(Queue_t* que){
    Node_t* tmp=que->front;
    for(int i=0; i<que->size; i++){
        printf("%d ",tmp->data);
        tmp=tmp->next;
    }
    printf("\n");
}

//队列 头出
int Quepop(Queue_t* que){
    if(que->size==0) {
        printf("队列为空\n");
        return -1;
    }
    Node_t* tmp=que->front;
    // if(que->size==1){
    //     que->tail=NULL;    //不建议这样搞花活，代码可读性差，且隐式赋值容易出现野指针
    // }                
    // que->front=que->front->next;
    if(que->size==1){
        que->tail=NULL;
        que->front=NULL;
    } else {
        que->front=que->front->next;
    }
    int ans=tmp->data;
    free(tmp);
    --que->size;
    return ans;
}

//队列 尾入
int Quepush(Queue_t* que,int data){
    if(que->size==que->maxsize) return -1;
    Node_t *node=(Node_t *) calloc(1,sizeof(Node_t));
    node->data=data;
    if(que->size==0){
        que->front=node;
        que->tail=node;
    }else{
        que->tail->next=node;
        que->tail=node;
    }
    ++que->size;
    return 1;
}

void *consumer(void* arg){
    Share_t *share=(Share_t*) arg;
    sleep(5);
    while(1){
        pthread_mutex_lock(&share->mutx);
        while(share->que->size==0){
            pthread_cond_wait(&share->cons_cond,&share->mutx);
        }
        printf("消费者开始消费：");
        int tmp=Quepop(share->que);
        printf("%d号产品被使用\n",tmp);
        pthread_cond_signal(&share->prod_cond);
        pthread_mutex_unlock(&share->mutx);
        sleep(1);
    }
    return NULL;
}

void *producer(void* arg){
    Share_t* share=(Share_t *)arg;
    while(1){
        pthread_mutex_lock(&share->mutx);
        while(share->que->size==share->que->maxsize){
            pthread_cond_wait(&share->prod_cond,&share->mutx);
        }
        int data=rand()%1000+1;
        Quepush(share->que,data);
        printf("生产者完成生产\n");
        pthread_cond_signal(&share->cons_cond);
        pthread_mutex_unlock(&share->mutx);
        sleep(1); 
    }
    return NULL; 
}



int main(){
    Share_t* share= (Share_t*) calloc(1,sizeof(Share_t));
    // 修正：传入指针的指针，正确初始化队列
    Queinit(&share->que,10);
    pthread_cond_init(&share->cons_cond,NULL);
    pthread_cond_init(&share->prod_cond,NULL);
    pthread_mutex_init(&share->mutx,NULL);

    pthread_t consArr[CONSUMERNUM]={0};
    pthread_t prodArr[PRODUCENUM]={0};
    for(int i=0;i<CONSUMERNUM;i++){
        // 修正：传入线程ID的地址
        pthread_create(&consArr[i],NULL,consumer,share);
    }
    for(int i=0;i<PRODUCENUM;i++){
        pthread_create(&prodArr[i],NULL,producer,share);
    }
    srand(time(0));
    sleep(60);
    for(int i=0;i<CONSUMERNUM;i++){
        pthread_cancel(consArr[i]);
    }
    for(int i=0;i<PRODUCENUM;i++){
        pthread_cancel(prodArr[i]);
    }
    for(int i=0;i<CONSUMERNUM;i++){
        pthread_join(consArr[i],NULL);
    }
    for(int i=0;i<PRODUCENUM;i++){
        pthread_join(prodArr[i],NULL);
    }
    pthread_cond_destroy(&share->cons_cond);
    pthread_cond_destroy(&share->prod_cond);
    pthread_mutex_destroy(&share->mutx);
    free(share->que);
    free(share);
    return 0;
}
